﻿/*************************************************************************
* 计算机名：AA-FA-05
* CLR 版本：4.0.30319.42000
* 命名空间: NModBusDrive
* 类    名：ModBusSerialPortTraport
* 当 前 域：HYRC
* 创 建 人：dailuyu
* 创建时间：2021/7/14 19:17:00
* 描    述：
*  V1.0.0.1 初版
*
*  Copyright (c) 2021 aatsr Corporation. All rights reserved.
*  ┌──────────────────────────────────┐
*  │　此技术信息为本公司机密信息，未经本公司书面同意禁止向第三方披露．　│
*  └──────────────────────────────────┘
***************************************************************************/
using NModBusDrive.Device;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NModBusDrive
{
    public class ModBusSerialPortWrapper : ModBusWrapper, IDisposable
    {
        private  IModbusMaster master;
        SerialPort port1;

        public override event CallBackData CallBackDataEvent;

        public override void Inin(string arg1, int port, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
        {
            port1 = new SerialPort(arg1, port, parity, dataBits, stopBits);
            master = ModbusSerialMaster.CreateRtu(port1);
        }

        public override void Connect()
        {
            try
            {
                if (port1.IsOpen == false)
                {
                    port1.Open();
                }
            }
            catch (Exception ex)
            {
                Logger.Error(string.Format("Modbus串口链接--Connect--->{0}\r\n{1}",ex.Message,ex.StackTrace));
            }
        }

        public override void Close()
        {
            if (port1.IsOpen == true)
            {
                port1.Close();
            }
        }

        public override void ReadCoil(ModBusOperType modBusOper, byte slaveAddress = 1, ushort startAddress = 0, ushort numberOfPoints = 0)
        {
            DataModel data = new DataModel() { ModBusOper=ModBusOperType.ReadCoil};
            switch (modBusOper)
            {
                case ModBusOperType.ReadCoils01: // 读取单个线圈
                    data.CoilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints);
                    break;
                case ModBusOperType.ReadDisCreteInputs02: // 读取输入线圈/离散量线圈
                    data.CoilsBuffer = master.ReadInputs(slaveAddress, startAddress, numberOfPoints);
                    break;
            }
            CallBackDataEvent?.Invoke(new TEventArgs<DataModel>(data));
        }

        public override void ReadRegister(ModBusOperType modBusOper, byte slaveAddress = 1, ushort startAddress = 0, ushort numberOfPoints = 0)
        {
            DataModel data = new DataModel() { ModBusOper = ModBusOperType.ReadRegister};
            switch (modBusOper)
            {
                case ModBusOperType.ReadHoldingRegisters03: // 读取保持寄存器
                    data.RegisterBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
                    break;
                case ModBusOperType.ReadInputRegisters04: // 读取输入寄存器
                    data.RegisterBuffer = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
                    break;
            }
            CallBackDataEvent?.Invoke(new TEventArgs<DataModel>(data));
        }

        public override async void WriteCoil(ModBusOperType modBusOper, byte slaveAddress = 1, ushort startAddress = 0, ushort numberOfPoints = 0, bool[] coilsBuffer = null)
        {
            switch (modBusOper)
            {
                case ModBusOperType.WriteSingleCoil05: // 写单个线圈
                    await master.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]);
                    break;
                case ModBusOperType.WriteMultipleCoils15: // 写一组线圈
                    await master.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer);
                    break;
            }
            //Logger.Info(string.Format("WriteRegister-->操作类型:{0} 从站地址:{1}  开始地址{2}  发送数据大小:{3}  发送真实数据:{4}  转换成二进制数据:{5} ",
            //    modBusOper, slaveAddress, startAddress, numberOfPoints, coilsBuffer[0]));
        }

        public override async void WriteRegister(ModBusOperType modBusOper, byte slaveAddress = 1, ushort startAddress = 0, ushort numberOfPoints = 0, ushort[] registerBuffer = null)
        {
            switch (modBusOper)
            {
                
                case ModBusOperType.WriteSingleRegisters06: // 写单个输入线圈/离散量线圈
                    await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);
                    Logger.Info(string.Format("WriteRegister-->操作类型:{0} 从站地址:{1}  开始地址{2}  发送数据大小:{3}  发送真实数据:{4}  转换成二进制数据:{5} 转换为16进制:{6}",
              modBusOper, slaveAddress, startAddress, numberOfPoints, registerBuffer[0], registerBuffer[0].ConvertToBinary(), String.Format("{0:X}", registerBuffer[0])));
                    break;
                case ModBusOperType.WriteMultipleRegisters16: // 写一组保持寄存器
                    await master.WriteMultipleRegistersAsync(slaveAddress, startAddress, new ushort[2] { registerBuffer.ConvertToDecimal(), (ushort)registerBuffer[16] });
                    Logger.Info(string.Format("WriteRegister-->操作类型:{0} 从站地址:{1}  开始地址{2}  发送数据大小:{3}  发送真实数据:{4}  转换成二进制数据:{5} 转换为16进制:{6} {7}",
              modBusOper, slaveAddress, startAddress, numberOfPoints, registerBuffer[0], registerBuffer[0].ConvertToBinary(), String.Format("{0:X}", registerBuffer[0]), String.Format("{0:X}", registerBuffer[1])));
                    break;
            }
        }
    }
}
